﻿#ifndef PST_LINECHARTTRACER_H
#define PST_LINECHARTTRACER_H

#include <limits>

#include "qcustomplot.h"
#include <QMap>
#include "PolarGraph.h"
#include "PostEnumType.h"
#include "DataModelPost.h"
class QDomElement;
class QDomDocument;
class QDomNodeList;
namespace pst
{
    class Curve2DPlotor;
    class LineChartTracer : public QCPItemTracer
    {
        Q_OBJECT
    public:
        explicit LineChartTracer(QCustomPlot* parentPlot);
        virtual ~LineChartTracer();

        /// @brief 文件写出至工程文件
        virtual QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* element, GraphType type = GraphType::None, bool isdiso = false);

        /// @brief 从工程文件读入数据
        virtual void readFromProjectFile(QDomElement* element, GraphType type = GraphType::None, bool isdiso = false);
        virtual void setCurveInfoID(int curveInfoID)
        {
            m_curveInfoID = curveInfoID;
        }
        virtual int getCurveInfoID() const
        {
            return m_curveInfoID;
        }

        void SetOnlyShowTracer(bool isOnlyShowTracer)
        {
            m_isOnlyShowTracer = isOnlyShowTracer;
            if (m_isOnlyShowTracer)
            {
                m_label->setVisible(false);
                m_arrow->setVisible(false);
                m_showLabelAndArrow = false;
            }
            else
            {
                m_label->setVisible(mVisible);
                m_arrow->setVisible(mVisible);
                m_showLabelAndArrow = true;
            }
        }

        bool GetOnlyShowTracer() const
        {
            return m_isOnlyShowTracer;
        }

        void SetValue(double value)
        {
            m_value = value;
        }

        double GetValue() const
        {
            return m_value;
        }

        void SetName(const QString& name)
        {
            m_name = name;
            m_label->setText(name);
        }

        QString GetName() const
        {
            return m_name;
        }

        void SetLayerable(QCPLayerable* layerable)
        {
            m_layerable = layerable;
        }

        QCPLayerable* GetLayerable() const
        {
            return m_layerable;
        }

        QCPItemText* GetLabel() const
        {
            return m_label;
        }

        QCPItemLine* GetArrow() const
        {
            return m_arrow;
        }

        virtual bool visible()
        {
            return mVisible;
        }

        virtual void setVisible(bool on)
        {
            mVisible = on;
            if (!m_isOnlyShowTracer)
            {
                m_label->setVisible(on);
                m_arrow->setVisible(on);
                m_showLabelAndArrow = on;
            }
        }
        //设置trace是否满足测量条件
        void setMeasurementConditionsIsSatisfied(bool isSatisfied)
        {
            m_isMeasurementConditionsSatisfied = isSatisfied;
        }

        bool getMeasurementConditionsIsSatisfied()
        {
            return m_isMeasurementConditionsSatisfied;
        }

        void setPolarGraph(QCPPolarGraph* graph)
        {
            m_polarGraph = graph;
        }
        QCPPolarGraph* getPolarGraph()
        {
            return m_polarGraph;
        }

        void setGraphAngle(double angle)
        {
            if (angle < -180)
            {
                angle += 360.0;
            }
            m_graphAngle = angle;
        }

        double getGraphAngle() const
        {
            return m_graphAngle;
        }

        QPointF getPolarGraphCoord() const
        {
            return QPointF(m_polarAngleCoord, m_polarRadiusCoord);
        }

        double getPolarGraphAngleCoord()
        {
            return m_polarAngleCoord;
        }

        double getPolarGraphRadiusCoord()
        {
            return m_polarRadiusCoord;
        }

        void updatePositionOnPolar();

        void setTracerIndex(int index) { m_tracerIndex = index; };
        int getTracerIndex() const { return m_tracerIndex; };

        void setStyle2DTracerProperty(Style2D_TracerProperty* style2D_TracerProperty);
        Style2D_TracerProperty* getStyle2DTracerProperty();

    public slots:
        virtual void slot_selectChange(bool selected);

    protected:
        void mousePressEvent(QMouseEvent* event, const QVariant& details) override;
        void mouseMoveEvent(QMouseEvent* event, const QPointF& startPos) override;
        virtual void draw(QCPPainter* painter) Q_DECL_OVERRIDE;

        int m_curveInfoID{-1};
        int m_tracerIndex{-1};
        bool m_isOnlyShowTracer;
        double m_value;
        QString m_name;
        QCPLayerable* m_layerable;
        QCPItemText* m_label;
        QCPItemLine* m_arrow;

        QCPPolarGraph* m_polarGraph{nullptr};
        double m_graphAngle{std::numeric_limits<double>::quiet_NaN()};
        double m_polarAngleCoord{0.0};
        double m_polarRadiusCoord{0.0};
        bool m_showLabelAndArrow{true};
        bool m_isMeasurementConditionsSatisfied{true};
        Style2D_TracerProperty* m_style2D_TracerProperty = nullptr;

    private:
    };

    class BeamBandwidthTracer : public LineChartTracer
    {
        Q_OBJECT
    public:
        explicit BeamBandwidthTracer(QCustomPlot* parentPlot);
        ~BeamBandwidthTracer();

        QCPItemLine* GetIndicator() const
        {
            return m_indicator;
        }

        /// @brief 文件写出至工程文件
        QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* element, GraphType type = GraphType::None, bool isdiso = false) override;

        /// @brief 从工程文件读入数据
        void readFromProjectFile(QDomElement* element, GraphType type = GraphType::None, bool isdiso = false) override;

        bool visible() override
        {
            return m_label->visible();
        }

        void setVisible(bool on) override
        {
            mVisible = false;
            if (!m_isOnlyShowTracer)
            {
                m_label->setVisible(on);
                m_arrow->setVisible(on);
                m_indicator->setVisible(on);
                m_showLabelAndArrow = on;
            }
        }

        double GetStandingWwaveValue() const
        {
            return m_standingWwaveValue;
        }

        void SetStandingWwaveValue(double value)
        {
            m_standingWwaveValue = value;
        }

        //是否完成了测量
        inline void setIsMeasured(bool isMeasured)
        {
            m_isMeasured = isMeasured;
        }
        //是否完成了测量

        inline bool isMeasured() const
        {
            return m_isMeasured;
        }

    public slots:
        void slot_selectChange(bool selected) override;

    protected:
#if 0
        virtual void draw(QCPPainter* painter) Q_DECL_OVERRIDE;
#endif

    private:
        QCPItemLine* m_indicator;
        double m_standingWwaveValue;
        bool m_isMeasured{false};
    };

    class TracerTableWidget : public QTableWidget
    {
        Q_OBJECT
    public:
        explicit TracerTableWidget(QCustomPlot* parent);

        virtual void AppendTracerProperty(LineChartTracer* tracer);

        void ShowValueProperty()
        {
            this->showColumn(3);
        }
        void HideValueProperty()
        {
            this->hideColumn(3);
        }

        bool m_isShowPreviewTracer = true;
        /// @brief 文件写出至工程文件
        virtual QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* element, GraphType graphType, bool isdiso = false);

        /// @brief 从工程文件读入数据
        virtual void readFromProjectFile(QDomNodeList* nodelist, QCustomPlot* customPlot, GraphType graphType, bool isdiso = false);


    public slots:
        virtual void slot_updateTracerProperty();
        virtual void slot_updateTracerChange();
        void contextMenuRequest(QPoint pos);
        QString exportDatas();
        void setFileName(QString fileName);

    signals:
        void signal_doubleClicked(LineChartTracer* tracer);
        void signal_removeMarkerSelect();
        void signal_removeMarkerAll();
        void signal_enableTracer();
        void signal_disableTracer();

    protected:
        // virtual bool eventFilter(QObject* obj, QEvent* event);

        QMenu* m_contextMenu;
        QString m_fileName;
    };

    class MeasureTableWidget : public QTableWidget
    {
        Q_OBJECT
    public:
        explicit MeasureTableWidget(QCustomPlot* parent);

        virtual void AppendTracerProperty(LineChartTracer* tracer);
        /// @brief 文件写出至工程文件
        virtual QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* element, bool isdiso = false);

        /// @brief 从工程文件读入数据
        virtual void readFromProjectFile(QDomNodeList* nodelist, QCustomPlot* customPlot, bool isdiso = false);

    public slots:
        virtual void slot_updateTracerProperty();
        virtual void slot_updateTracerChange();
        void contextMenuRequest(QPoint pos);
        void exportDatas();

    signals:
        void signal_doubleClicked(LineChartTracer* tracer);

    protected:
        // virtual bool eventFilter(QObject* obj, QEvent* event);

        QMenu* m_contextMenu;
    };
} // namespace pst
#endif // PST_LINECHARTTRACER_H
